home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / mweb / MWEB Utils / ws295sdk.exe / Ws2sdkzp.exe / SAMPLES / LAYERED / TRACE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-06  |  7.8 KB  |  280 lines

  1. /*++
  2.  
  3.      Copyright (c) 1996 Intel Corporation
  4.      Copyright (c) 1996 Microsoft Corporation
  5.      All Rights Reserved
  6.  
  7.      Permission is granted to use, copy and distribute this software and
  8.      its documentation for any purpose and without fee, provided, that
  9.      the above copyright notice and this statement appear in all copies.
  10.      Intel makes no representations about the suitability of this
  11.      software for any purpose.  This software is provided "AS IS."
  12.  
  13.      Intel specifically disclaims all warranties, express or implied,
  14.      and all liability, including consequential and other indirect
  15.      damages, for the use of this software, including liability for
  16.      infringement of any proprietary rights, and including the
  17.      warranties of merchantability and fitness for a particular purpose.
  18.      Intel does not assume any responsibility for any errors which may
  19.      appear in this software nor any responsibility to update it.
  20.  
  21. Module Name:
  22.  
  23.     TRACE.CPP :
  24.  
  25. Abstract:
  26.  
  27.     This module implements the traceing functions used in the winsock2 layered
  28.     service provider example.
  29.  
  30.  
  31. --*/
  32. #define WIN32_LEAN_AND_MEAN
  33. #include "nowarn.h"
  34.  
  35. #include <winsock2.h>
  36. #include <memory.h>
  37. #include <stdio.h>
  38. #include <stdarg.h>
  39. #include <io.h>
  40. #include <malloc.h>
  41.  
  42. /* because windows.h is brain damaged and turns this one back on */
  43. #pragma warning(disable: 4001)
  44.  
  45. #include "trace.h"
  46.  
  47. #ifdef TRACING
  48.  
  49. //
  50. // Internal functions
  51. //
  52. BOOL  InitMemoryBuffers(VOID);
  53.  
  54. //
  55. // Module local variables
  56. //
  57.  
  58. // The buffers to use to format debug messages.
  59. LPSTR g_CurrentMessage=NULL;
  60. LPSTR g_PreviousMessage=NULL;
  61.  
  62. // Critcal section to keep multiple thread from walking on each others output
  63. CRITICAL_SECTION OutputRoutine;
  64.  
  65. // Where should the output go? If it is a file what is the file name
  66. int iTraceDestination=TRACE_TO_AUX;
  67. char TraceFile[] = "trace.log";
  68.  
  69. // The default output level
  70. DWORD debugLevel=0xFFFFFFFF;
  71.  
  72.  
  73.  
  74. VOID
  75. PrintDebugString(
  76.                  char *Format,
  77.                  ...
  78.                  )
  79. /*++
  80.   Routine Description:
  81.  
  82.   This routine outputs a debug messages.  Debug messages are routed
  83.   to a file or a debug window depnding on the value of a global
  84.   variable defined in this module
  85.  
  86.   Arguments:
  87.  
  88.   Format - A "printf()" compatable format specification.
  89.  
  90.   ... - Additional arguments to "printf()" format specification.
  91.  
  92.   Returns:
  93.  
  94.   NONE
  95.  
  96.   --*/
  97. {
  98.     va_list ArgumentList; // argument list for varargs processing
  99.     static HANDLE OutputFile =NULL; // file descriptor for file output
  100.     static OFSTRUCT of; // open file struct for file output
  101.     static int RepeatCount=0; // Count of repeated output statements
  102.     static BOOL LogOpened = FALSE; // have we opened the file for
  103.                                      // output
  104.     static BOOL TraceInited = FALSE;
  105.     DWORD  BytesWritten;
  106.  
  107.     if (!TraceInited)
  108.     {
  109.         HANDLE InitMutex;
  110.         // Create the mutex to protect the rest of the init code
  111.         InitMutex = CreateMutex(
  112.             NULL,  // Use default security attributes
  113.             FALSE, // We don't want automatic ownership
  114.             "TraceMutextName");
  115.         if (!InitMutex)
  116.         {
  117.             // We failed to create the mutex there is nothign else we
  118.             // can do so return.  This will cause the debug output to
  119.             // be silently lost.
  120.             return;
  121.         } //if
  122.  
  123.         // Wait on mutex
  124.         WaitForSingleObject( InitMutex,
  125.                              INFINITE);
  126.  
  127.         // Check to see if init is still needed
  128.         if (!TraceInited)
  129.         {
  130.             // Init the critical section to be used to protect the
  131.             // output portion of this routine.
  132.             InitializeCriticalSection( &OutputRoutine );
  133. // Note:
  134. // DeleteCriticalSection will not be called on this critical section
  135. // we are reling on the OS to clean this one up.  We are doing this so
  136. // the user of this module does not have to Init/DeInit the module explicitly.
  137.  
  138.             // allocate buffers to hold debug messages
  139.             if (InitMemoryBuffers())
  140.             {
  141.                 TraceInited = TRUE;
  142.             } //if
  143.         } //if
  144.  
  145.         // Signal the mutex and delete this threads handle to the mutex
  146.         ReleaseMutex(InitMutex);
  147.         CloseHandle(InitMutex);
  148.     }
  149.  
  150.  
  151.     // Here is where all the heavy lifting starts
  152.     EnterCriticalSection( &OutputRoutine );
  153.  
  154.     // print the user message to our buffer
  155.     va_start(ArgumentList, Format);
  156.     vsprintf(g_CurrentMessage, Format, ArgumentList);
  157.     va_end(ArgumentList);
  158.  
  159.     // Is the current debug message the same as the last debug
  160.     // message?  If the two messages are the same just increment the
  161.     // count of message repeats and return.  This keeps the system
  162.     // from being flooded with debug messages that may be being
  163.     // generated from inside a loop.
  164.  
  165.     if(lstrcmp(g_CurrentMessage, g_PreviousMessage))
  166.     {
  167.         if (iTraceDestination == TRACE_TO_FILE)
  168.         {
  169.             if (!LogOpened)
  170.             {
  171.                 OutputFile =
  172.                 CreateFile( TraceFile,
  173.                             GENERIC_WRITE,     // open for writing
  174.                             FILE_SHARE_WRITE,  // Share the file with others
  175.                             NULL,              // default security
  176.                             OPEN_ALWAYS,       // Use file if it exsits
  177.                             FILE_ATTRIBUTE_NORMAL, // Use a normal file
  178.                             NULL);             // No template
  179.  
  180.                 if (OutputFile != INVALID_HANDLE_VALUE)
  181.                 {
  182.                     LogOpened = TRUE;
  183.                 } //if
  184.             } //if
  185.  
  186.             if (LogOpened)
  187.             {
  188.                 if (RepeatCount > 0)
  189.                 {
  190.                     wsprintf(g_PreviousMessage,
  191.                              "Last Message Repeated < %d > times\n",
  192.                              RepeatCount);
  193.  
  194.                     WriteFile(OutputFile,
  195.                               g_PreviousMessage,
  196.                               lstrlen(g_PreviousMessage),
  197.                               &BytesWritten,
  198.                               NULL);
  199.                 } //if
  200.  
  201.                 // Write the current message to the trace file
  202.                 WriteFile(OutputFile,
  203.                           g_CurrentMessage,
  204.                           lstrlen(g_CurrentMessage),
  205.                           &BytesWritten,
  206.                           NULL);
  207.  
  208.                 // Flush debug output to file
  209.                 FlushFileBuffers( TraceFile );
  210.  
  211.                 //reset the repeat count
  212.                 RepeatCount =0;
  213.             } //if
  214.         }
  215.  
  216.         if( iTraceDestination == TRACE_TO_AUX)
  217.         {
  218.             if(RepeatCount > 0)
  219.             {
  220.                 wsprintf(g_PreviousMessage,
  221.                          "Last Message Repeated < %d > times\n",
  222.                          RepeatCount);
  223.                 OutputDebugString(g_PreviousMessage);
  224.                 RepeatCount = 0;
  225.             }
  226.             // Send message to AUX device
  227.             OutputDebugString(g_CurrentMessage);
  228.         }
  229.         // Store off this message
  230.         lstrcpy(g_PreviousMessage, g_CurrentMessage);
  231.     }
  232.     else
  233.     {
  234.         RepeatCount++;
  235.     }
  236.     LeaveCriticalSection( &OutputRoutine );
  237. }
  238.  
  239.  
  240.  
  241.  
  242. BOOL
  243. InitMemoryBuffers(
  244.                   VOID
  245.                   )
  246. /*++
  247.   Routine Description:
  248.  
  249.   Initailizes the memory buffers used by this module.
  250.  
  251.   Arguments:
  252.  
  253.   NONE
  254.  
  255.   Returns:
  256.  
  257.   TRUE if all memory buffers are successfully created, Otherwise FALSE.
  258.  
  259.   --*/
  260. {
  261.     BOOL ReturnCode=FALSE;
  262.  
  263.     g_CurrentMessage = (LPSTR)malloc(TRACE_OUTPUT_BUFFER_SIZE);
  264.     if (g_CurrentMessage)
  265.     {
  266.         g_PreviousMessage = (LPSTR)malloc(TRACE_OUTPUT_BUFFER_SIZE);
  267.         if (g_PreviousMessage)
  268.         {
  269.             ReturnCode=TRUE;
  270.         } //if
  271.         else
  272.         {
  273.             free( g_CurrentMessage );
  274.         } //else
  275.     } //if
  276.     return(ReturnCode);
  277. }
  278.  
  279. #endif  // TRACING
  280.